package com.example.pet.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.pet.beans.MsgInfo;
import com.example.pet.mapper.IMsgInfoMapper;
import com.example.pet.service.IMsgInfoService;
import com.example.pet.service.impl.MsgInfoServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author liukai
 * @version 1.0.0
 * @ClassName WebSocketServer.java
 * @Description TODO
 * @createTime 2021年04月27日 10:31:00
 */
@ServerEndpoint("/websocket/{userId}")
@Component
@Slf4j
public class WebSocketServer implements ApplicationContextAware {


    //静态变量，用来记录当前在线连接数。把它设计成线程安全的。
    private static AtomicInteger onlineCount = new AtomicInteger();

    //用来存放每个客户端对应的WebSocketServer对象
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    //    消息服务层
    private static MsgInfoServiceImpl msgInfoService;

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                log.info("发送数据:{}", message);
                session.getBasicRemote().sendText(message.toString());
            }
        }
    }

    //给指定用户发送信息
    public void sendInfo(String userId, JSONObject message) {
        Session session = sessionPools.get(userId);
        log.info("给[{}], session:{}", userId, session);
        try {
            sendMessage(session, message.toJSONString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //给指定用户发送信息
    public void sendInfo(String userId, String message) {
        Session session = sessionPools.get(userId);
        log.info("给[{}], session:{}", userId, session);
        try {
            sendMessage(session, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        sessionPools.put(userId, session);
        addOnlineCount();
        log.info("[{}]加入webSocket，当前人数为:{}，session:{}", userId, onlineCount, session);
        try {
//            sendMessage(session, "欢迎[" + userId + "]加入连接！");

        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("人员信息:{}", sessionPools);
    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "userId") String userId) {
        sessionPools.remove(userId);
        subOnlineCount();
        log.info("[{}]断开webSocket连接，当前人数为:{}", userId, onlineCount);
    }

    /**
     * 收到客户端信息
     */
    @OnMessage
    public void onMessage(String message) throws IOException {

        MsgInfo msgInfo = JSONArray.parseObject(message, MsgInfo.class);
        System.out.println("收到消息" + msgInfo.toString());

        // 如果消息有接收者，则将消息发送给接收者，存入数据库
        if (msgInfo.getReceiveId() != null && !msgInfo.getReceiveId().equals("")) {
            // 给指定用户发送消息
            sendInfo(msgInfo.getReceiveId(), msgInfo.getMsg());
            // 将消息存入数据库
            String id = UUID.randomUUID().toString();
            msgInfo.setSendTime(new Date()).setId(id);
            int i = msgInfoService.addMsg(msgInfo);
        } else {
//            sendInfo(msgInfo.getReceiveId(),msgInfo.getMsg());
        }


//
//        log.info("客户端[{}]已收到", message);
//        message = "客户端：" + message + ",已收到";
//        for (Session session : sessionPools.values()) {
//            try {
//                sendMessage(session, message);
//            } catch (Exception e) {
//                e.printStackTrace();
//                continue;
//            }
//        }
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("发生错误:{}", session);
        throwable.printStackTrace();
    }


    /**
     * 人数加1
     */
    public static void addOnlineCount() {
        onlineCount.incrementAndGet();
    }

    /**
     * 人数减1
     */
    public static void subOnlineCount() {
        onlineCount.decrementAndGet();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        msgInfoService = applicationContext.getBean(MsgInfoServiceImpl.class);
    }


}
